package com.hatic.money;

import java.util.List;
import java.util.Map;

import org.jxstar.control.action.RequestContext;
import org.jxstar.dao.DaoParam;
import org.jxstar.service.BusinessObject;
import org.jxstar.util.DateUtil;
import org.jxstar.util.StringUtil;
import org.jxstar.util.key.KeyCreator;

/**
 * 根据投资计划生成项目记录。
 *
 * @author TonyTan
 * @version 1.0, 2011-10-02
 */
public class PlanAuthBO extends BusinessObject {
	private static final long serialVersionUID = 1L;
	
	/**
	 * 授权时撤销投资计划，不能是结转计划
	 * @param planIds
	 * @return
	 */
	public String cancel(String[] planIds) {
		if (planIds == null || planIds.length == 0) {
			setMessage("没有选择投资计划！");
			return _returnFaild;
		}
		
		for (int i = 0; i < planIds.length; i++) {
			Map<String,String> mpPlan = queryPlan(planIds[i]);
			String is_turn = mpPlan.get("is_turn");
			String plan_code = mpPlan.get("plan_code");
			
			if (is_turn.equals("1")) {
				setMessage("【{0}】是结转投资计划，不能撤销！", plan_code);
				return _returnFaild;
			}
			
			updateStatus(planIds[i], "91");
		}
		
		return _returnSuccess;
	}
	
	//提交审批流程前的检查，授权形式与授权单位不能为空
	public String authCheck(String[] planIds) {
		if (planIds == null || planIds.length == 0) {
			setMessage("没有选择投资计划！");
			return _returnFaild;
		}
		
		for (int i = 0, n = planIds.length; i < n; i++) {
			Map<String,String> mpPlan = queryPlan(planIds[i]);
			
			String plan_code = mpPlan.get("plan_code");//计划编号
			String auth_type = mpPlan.get("auth_type");//授权形式
			String done_deptname = mpPlan.get("done_deptname");//实施单位

			if (auth_type.length() == 0 || done_deptname.length() == 0) {
				setMessage(plan_code + "投资计划没有设置授权形式与实施单位，不能提交！");
				return _returnFaild;
			}
		}
		
		return _returnSuccess;
	}
	
	/**
	 * 批量授权：更新投资计划中的授权形式与实施单位，状态改为待下达
	 * @param request
	 * @return
	 */
	public String projectAuth(RequestContext request) {
		String auth_date = request.getRequestValue("money_plan.auth_date");
		String auth_type = request.getRequestValue("money_plan.auth_type");
		String auth_user = request.getRequestValue("money_plan.auth_user");
		String auth_userid = request.getRequestValue("money_plan.auth_userid");
		String done_deptname = request.getRequestValue("money_plan.done_deptname");
		String done_deptid = request.getRequestValue("money_plan.done_deptid");
		String dept_name = request.getRequestValue("money_plan.dept_name");
		String dept_id = request.getRequestValue("money_plan.dept_id");
		if (auth_date.length() == 0 || auth_type.length() == 0 ||
				done_deptname.length() == 0 || done_deptid.length() == 0) {
			setMessage("投资计划的分级授权信息不完整！");
			return _returnFaild;
		}
		
		String[] planIds = request.getRequestValues("keyid");
		if (planIds == null || planIds.length == 0) {
			setMessage("没选择需要授权的投资计划！");
			return _returnFaild;
		}
		
		for (int i = 0; i < planIds.length; i++) {
			String planId = planIds[i];
			
			if (!updateAuth(planId, auth_date,  auth_type, 
					auth_user, auth_userid, done_deptname, done_deptid,dept_name,dept_id)) {
				setMessage("修改投资计划授权信息出错！");
				return _returnFaild;
			}
			
			//如果是虚拟包或大计划，则需要更新子计划信息
			Map<String,String> mpDept = getPlanData(planId);
			String baoType = mpDept.get("bao_type");
			if (baoType.equals("1") || baoType.equals("2")) {
				if (!updateSubAuth(planId, auth_date,  auth_type, 
						auth_user, auth_userid, done_deptname, done_deptid,dept_name,dept_id)) {
					setMessage("修改子投资计划授权信息出错！");
					return _returnFaild;
				}
			}
		}
		
		return _returnSuccess;
	}
	
	/**
	 * 部分授权： 更新投资计划中的授权形式与实施单位，状态改为待下达
	 * @param planIds
	 * @param auth_type -- 授权类型：部分 bf、完全 wq
	 * @param auth_user
	 * @param auth_userid
	 * @return
	 */
	public String projectAuthBf(String[] planIds, String auth_type, String auth_user, String auth_userid) {
		String auth_date = DateUtil.getToday();

		if (planIds == null || planIds.length == 0) {
			setMessage("没选择需要授权的投资计划！");
			return _returnFaild;
		}
		
		for (int i = 0; i < planIds.length; i++) {
			String planId = planIds[i];
			
			Map<String,String> mpDept = getPlanData(planId);
			String deptId = mpDept.get("dept_id");
			String rootId = deptId.substring(0, 4);
			String deptName = mpDept.get("dept_name");
			
			String doneDeptId = DeviceDept.getDeptId(rootId);
			String doneDeptName = DeviceDept.getDeptName(rootId);
			
			if (!updateAuth(planId, auth_date,  auth_type, 
					auth_user, auth_userid, doneDeptName, doneDeptId,deptName,deptId)) {
				setMessage("修改投资计划授权信息出错！");
				return _returnFaild;
			}
			
			//如果是虚拟包或大计划，则需要更新子计划信息
			String baoType = mpDept.get("bao_type");
			if (baoType.equals("1") || baoType.equals("2")) {
				if (!updateSubAuth(planId, auth_date,  auth_type, 
						auth_user, auth_userid, doneDeptName, doneDeptId,deptName,deptId)) {
					setMessage("修改子投资计划授权信息出错！");
					return _returnFaild;
				}
			}
		}
		
		return _returnSuccess;
	}
	
	/**
	 * 填写批复信息
	 * @param request
	 * @return
	 */
	public String projectCheck(RequestContext request) {
		String fileno = request.getRequestValue("money_plan.check_fileno");
		String filename = request.getRequestValue("money_plan.check_name");
		if (fileno.length() == 0 || filename.length() == 0) {
			setMessage("投资计划的批复信息不完整！");
			return _returnFaild;
		}
		
		String[] planIds = request.getRequestValues("keyid");
		if (planIds == null || planIds.length == 0) {
			setMessage("没选择需要下达的投资计划！");
			return _returnFaild;
		}
		
		for (int i = 0; i < planIds.length; i++) {
			String planId = planIds[i];
			
			//结转计划的计划批复文号累加
			if (!updateCheck(planId, fileno, filename, false)) {
				setMessage("更新项目批复信息出错！");
				return _returnFaild;
			}
			
			//如果是虚拟包或大计划，则需要更新子计划信息
			Map<String,String> mpDept = getPlanData(planId);
			String baoType = mpDept.get("bao_type");
			if (baoType.equals("1") || baoType.equals("2")) {
				if (!updateCheck(planId, fileno, filename, true)) {
					setMessage("更新项目批复信息出错！");
					return _returnFaild;
				}
			}
		}
		
		return _returnSuccess;
	}
	
	/**
	 * 批量下达：更新投资计划中的计划批复文号、批复文件名；更新状态为待实施；
	 *          结转的投资计划的批复文号不修改，父计划的批复文号不需要反馈。
	 * 
	 * @param request
	 * @return
	 */
	public String projectDown(String[] planIds, String userId) {
		if (planIds == null || planIds.length == 0) {
			setMessage("没选择需要下达的投资计划！");
			return _returnFaild;
		}
		
		for (int i = 0; i < planIds.length; i++) {
			String planId = planIds[i];
			
			Map<String,String> plandata = queryPlan(planId);
			String check_name = plandata.get("check_name");
			String check_fileno = plandata.get("check_fileno");
			if (check_name.length() == 0 || check_fileno.length() == 0) {
				setMessage("选择的投资计划没有批复文号，不能下达！");
				return _returnFaild;
			}
			
			//包属性
			String baoType = plandata.get("bao_type");
			
			//如果是结转的投资计划，如果是实施中的计划，则状态改为实施中；
			String is_turn = plandata.get("is_turn");
			String old_status = plandata.get("oldplan_status");
			if (is_turn.equals("1")) {
				updateStatus(planId, old_status);
			} else {
				updateStatus(planId, "41");
			}
			
			//年度新增的投资计划需要生成项目立项申请，虚拟包不产生项目
			if (is_turn.equals("0") && !baoType.equals("1")) {
				if (!projectCreate(planId, userId)) {
					setMessage("创建项目信息出错！");
					return _returnFaild;
				}
			} 
			
			//如果是虚拟包或大计划，其新增的子计划需要生成项目
			if (baoType.equals("1") || baoType.equals("2")) {
				List<Map<String,String>> lssub = querySubPlan(planId);
				for (int j = 0, m = lssub.size(); j < m; j++) {
					Map<String,String> mpsub = lssub.get(j);
					String subPlanId = mpsub.get("plan_id");
					String subIsTurn = plandata.get("is_turn");
					String subOldStatus = plandata.get("oldplan_status");
					
					if (subIsTurn.equals("1")) {
						updateStatus(subPlanId, subOldStatus);
					} else {
						updateStatus(subPlanId, "41");
					}
					
					if (subIsTurn.equals("0")) {
						if (!projectCreate(subPlanId, userId)) {
							setMessage("创建项目信息出错！");
							return _returnFaild;
						}
					}
				}
			}
			
		}
		
		return _returnSuccess;
	}
	
	//更新项目授权信息
	private boolean updateAuth(String planId, String auth_date, String auth_type, 
			String auth_user, String auth_userid, String done_deptname, 
			String done_deptid,String dept_name, String dept_id) {
		
		String usql = "update money_plan set auth_date = ?, auth_type = ?, auth_user = ?, auth_userid = ?," +
				"done_deptname = ?, done_deptid = ?, dept_name =?,dept_id =?  where plan_id = ?";
		
		DaoParam param = _dao.createParam(usql);
		param.addDateValue(auth_date);
		param.addStringValue(auth_type);
		param.addStringValue(auth_user);
		param.addStringValue(auth_userid);
		param.addStringValue(done_deptname);
		param.addStringValue(done_deptid);
		param.addStringValue(dept_name);
		param.addStringValue(dept_id);
		param.addStringValue(planId);
		
		return _dao.update(param);
	}
	
	//更新子项目的授权信息
	private boolean updateSubAuth(String planId, String auth_date, String auth_type, 
			String auth_user, String auth_userid, String done_deptname, 
			String done_deptid,String dept_name, String dept_id) {
		
		String usql = "update money_plan set auth_date = ?, auth_type = ?, auth_user = ?, auth_userid = ?," +
				"done_deptname = ?, done_deptid = ?, dept_name =?, dept_id =?  where plan_parentid = ?";
		
		DaoParam param = _dao.createParam(usql);
		param.addDateValue(auth_date);
		param.addStringValue(auth_type);
		param.addStringValue(auth_user);
		param.addStringValue(auth_userid);
		param.addStringValue(done_deptname);
		param.addStringValue(done_deptid);
		param.addStringValue(dept_name);
		param.addStringValue(dept_id);
		param.addStringValue(planId);
		
		return _dao.update(param);
	}
	
	//更新部分授权信息
	/*private boolean updateAuthbf(String planId, String auth_date, String auth_type, 
			String auth_user, String auth_userid) {
		
		String usql = "update money_plan set auth_date = ?, auth_type = ?, auth_user = ?, auth_userid = ?," +
				"done_deptname = dept_name, done_deptid = dept_id where plan_id = ?";
		
		DaoParam param = _dao.createParam(usql);
		param.addDateValue(auth_date);
		param.addStringValue(auth_type);
		param.addStringValue(auth_user);
		param.addStringValue(auth_userid);
		param.addStringValue(planId);
		
		return _dao.update(param);
	}*/	
	
	//更新项目批复信息
	private boolean updateCheck(String planId, String fileno, String filename, boolean isSub) {
		String usql = "update money_plan set check_fileno = ?, check_name = ? ";
		if (isSub) {
			usql += "where plan_parentid = ?";
		} else {
			usql += "where plan_id = ?";
		}

		DaoParam param = _dao.createParam(usql);
		param.addStringValue(fileno);
		param.addStringValue(filename);
		param.addStringValue(planId);
		return _dao.update(param);
	}
	
	//更新项目状态
	private boolean updateStatus(String planId, String state) {
		String usql = "update money_plan set plan_status = ? where plan_id = ?";
		DaoParam param = _dao.createParam(usql);
		param.addStringValue(state);
		param.addStringValue(planId);
		
		return _dao.update(param);
	}
	
	public boolean projectCreate(String planId, String userId) {
		return projectCreate(planId, userId, "");
	}
	
	/**
	 * 产生项目，虚拟包不产生项目，其它包类别的产生项目
	 * @param planId -- 计划ID
	 * @param userId -- 用户ID
	 * @param parentPlanId -- 父计划ID
	 * @return
	 */
	public boolean projectCreate(String planId, String userId, String parentPlanId) {
		if (planId == null || planId.length() == 0) {
			_log.showError("没有创建项目的计划ID与包属性！");
			return false;
		}
		
		String parentId = "", parentCode = "",parentbaotype="";
		String projbaotype  = "0";
		if (parentPlanId != null && parentPlanId.length() > 0) {
			Map<String,String> mpParent = getParentProject(parentPlanId);
			parentId = mpParent.get("project_id");
			parentCode = mpParent.get("project_code");
			parentbaotype = mpParent.get("bao_type");
			if(StringUtil.tonum(parentbaotype) == 2){
				projbaotype = "7";
			}
		}
		
		//取投资计划的值
		Map<String,String> mpPlan = queryPlan(planId);
		//创建项目ID
		String projectId = KeyCreator.getInstance().createKey("project_base");
		//准备废除项目编号，直接采用计划编号，两者采用同一个编号
		String projectCode = mpPlan.get("plan_code");
		//String projectCode = CodeCreator.getInstance().createCode("project_create");
		_log.showDebug("-------------创建项目ID=" + projectId);
		
		//计算项目缺省的批复单位：1 国家局、2 省局、3 烟厂，如果有国家局的批复权限，则采用它，
		//否则，根据授权形式确定，完全授权采用烟厂审批，其它的采用省局审批。
		String checkType = mpPlan.get("check_right2");
		if (checkType == null || checkType.length() == 0) {
			String auth_type = mpPlan.get("auth_type");
			if (auth_type.equals("wq")) {
				checkType = "3";
			} else {
				checkType = "2";
			}
		}
		
		//大计划对应的项目包属性是大项目
		String baoType = mpPlan.get("bao_type");
		if(StringUtil.tonum(baoType) == 2){
			projbaotype = "2";
		}
		
		String isql = "insert into project_base(" +
				"project_id, project_code, project_date, auditing, add_userid, add_date," +  
				"plan_code, plan_id, project_name, money_type, auth_type, project_money, dept_id, dept_name, project_status," +
				"check_fileno, check_name, plan_money, check_dept, project_content, done_deptid, done_deptname, bao_type," +
				"project_parentid, project_parentcode,projbao_type,auth_date)" +
				"values(?, ?, ?, ?, ?, ?, " + 
				"?, ?, ?, ?, ?, ?, ?, ?, '1', " +
				"?, ?, ?, ?, ?, ?, ?, ?, " +
				"?, ?, ?,?)";
		DaoParam iparam = _dao.createParam(isql);
		iparam.addStringValue(projectId);
		iparam.addStringValue(projectCode);
		iparam.addDateValue(DateUtil.getToday());
		iparam.addStringValue("0");
		iparam.addStringValue(userId);
		iparam.addDateValue(DateUtil.getToday());
		iparam.addStringValue(mpPlan.get("plan_code"));
		iparam.addStringValue(mpPlan.get("plan_id"));
		iparam.addStringValue(mpPlan.get("plan_name"));
		iparam.addStringValue(mpPlan.get("money_type"));
		iparam.addStringValue(mpPlan.get("auth_type"));
		iparam.addDoubleValue(mpPlan.get("plan_money"));
		iparam.addStringValue(mpPlan.get("dept_id"));
		iparam.addStringValue(mpPlan.get("dept_name"));
		//添加下面的项目缺省信息
		iparam.addStringValue(mpPlan.get("check_fileno"));
		iparam.addStringValue(mpPlan.get("check_name"));
		iparam.addDoubleValue(mpPlan.get("plan_money"));
		iparam.addStringValue(checkType);
		iparam.addStringValue(mpPlan.get("plan_desc"));
		iparam.addStringValue(mpPlan.get("done_deptid"));
		iparam.addStringValue(mpPlan.get("done_deptname"));
		iparam.addStringValue(mpPlan.get("bao_type"));
		iparam.addStringValue(parentId);
		iparam.addStringValue(parentCode);
		iparam.addStringValue(projbaotype);
		iparam.addDateValue(mpPlan.get("auth_date"));
		
		if (!_dao.update(iparam)) {
			_log.showError("创建新的项目记录出错！");
			return false;
		}
		
		String usql = "update money_plan set plan_status = '41', project_id = ?, project_code = ? where plan_id = ?";
		DaoParam uparam = _dao.createParam(usql);
		uparam.addStringValue(projectId);
		uparam.addStringValue(projectCode);
		uparam.addStringValue(planId);
		if (!_dao.update(uparam)) {
			_log.showError("更新投资计划的状态为实施中出错！");
			return false;
		}
		
		return true;
	}
	
	//取投资计划的值
	private Map<String,String> queryPlan(String planId) {
		//plan_code, plan_id, plan_name, money_type, auth_type, plan_money, done_deptid, done_deptname, oldplan_id, oldplan_status, is_turn
		//取所有字段，避免漏字段了
		String sql = "select * from money_plan where plan_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(planId);
		
		return _dao.queryMap(param);
	}

	//取投资计划部分信息
	private Map<String,String> getPlanData(String planId) {
		String sql = "select dept_id, bao_type from money_plan where plan_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(planId);
		
		return _dao.queryMap(param);
	}
	
	//取大计划中的新增子计划
	private List<Map<String,String>> querySubPlan(String planId) {
		String sql = "select plan_id, oldplan_status, is_turn from money_plan where plan_parentid = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(planId);
		
		return _dao.query(param);
	}
	
	//取父计划产生的项目编号
	private Map<String,String> getParentProject(String parentPlanId) {
		String sql = "select project_id, project_code ,bao_type from project_base where plan_id = ?";
		DaoParam param = _dao.createParam(sql);
		param.addStringValue(parentPlanId);
		
		return _dao.queryMap(param);
	}
}
